package com.taritari.journal.services;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.taritari.journal.entity.dto.JournalInfoDto;
import com.taritari.journal.entity.dto.RegisterDto;
import com.taritari.journal.entity.dto.UserDTO;
import com.taritari.journal.entity.po.JournalUser;
import com.taritari.journal.entity.vo.JournalNumberCountVo;
import com.taritari.journal.entity.vo.TodayJournalVo;
import com.taritari.journal.enums.ResultCode;
import com.taritari.journal.mapper.BrowseLogMapper;
import com.taritari.journal.mapper.JournalUserMapper;
import com.taritari.journal.services.impl.UserServiceImpl;
import com.taritari.journal.utils.DateUtil;
import com.taritari.journal.utils.JwtUtil;
import com.taritari.journal.utils.Result;
import com.taritari.journal.utils.RsaUtils;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author taritari
 * @date 2023-12-04 21:35
 * @description 用户
 */
@Slf4j
@Service
public class UserService extends ServiceImpl<JournalUserMapper, JournalUser> implements UserServiceImpl {
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private JournalUserMapper journalUserMapper;
    @Autowired
    private BrowseLogMapper browseLogMapper;
    @Autowired
    private DateUtil dateUtil;
    @Autowired
    private RsaUtils rsaUtils;
    /**
     * 登录
     * */
    public Result login(UserDTO userDTO) throws Exception {
        QueryWrapper<JournalUser> queryWrapper=new QueryWrapper<>();

        if (StringUtil.isNullOrEmpty(userDTO.getEmail())){
            queryWrapper.eq("username",userDTO.getUsername());
        }else {
            queryWrapper.eq("email",userDTO.getEmail());
        }
        JournalUser one;
        try{
            one=getOne(queryWrapper);
        }catch (Exception e){
            return Result.fail(ResultCode.ACCOUNT_OR_PASSWORD_ERROR);
        }
        if(one!=null){
            //判断密码是否正确
            String pwd = rsaUtils.decrypt(one.getPassword());
            //密码错误
            if (!pwd.equals(userDTO.getPassword())){
                return Result.fail();
            }
            //以下是登录判断业务
            BeanUtil.copyProperties(one,userDTO,true);
            //设置token
            String token = jwtUtil.generateToken(userDTO.getUsername());
            userDTO.setToken(token);
            //用户信息存到redis 3天过期
            stringRedisTemplate.opsForValue().set(userDTO.getUsername(), String.valueOf(userDTO.getId()),30 * 24 * 60 * 60, TimeUnit.SECONDS);
            userDTO.setPassword("");
            return Result.success(userDTO);
        }else {
            return Result.fail(ResultCode.ACCOUNT_OR_PASSWORD_ERROR);
        }
    }

    @Override
    public int tokenGetUserId(String token) {
        boolean tokenExpired = jwtUtil.isTokenExpired(token);
        if (tokenExpired){
            String username = jwtUtil.getClaimFiled(token, "username");
            String id = stringRedisTemplate.opsForValue().get(username);
            if (StrUtil.isNotEmpty(id)){
                return Integer.parseInt(id);
            }
        }else {
            return 0;
        }
        return 0;
    }

    @Override
    public Map<String,Object> getCountById(int id) {
        List<String> monthBetweenTailNow = dateUtil.getMonthBetweenTailNow(6);
        Map<String, Object> countList = new HashMap<>(8);
        List<Integer> writCounts = new ArrayList<>();
        List<Integer> viewCounts = new ArrayList<>();
        List<String> months = new ArrayList<>();
        Map<String,Object> seriesWrit = new HashMap<>();
        Map<String,Object> seriesView = new HashMap<>();
        for(String month : monthBetweenTailNow){
            int journalCountByMonth = journalUserMapper.getJournalCountByMonth(id, month);
            int viewCountByMonth = browseLogMapper.getViewCountByMonth(id, month);
            writCounts.add(journalCountByMonth);
            viewCounts.add(viewCountByMonth);
            months.add(dateUtil.yearMonth2Month(month));
        }
        seriesWrit.put("name","写作量");
        seriesWrit.put("data",writCounts);
        seriesView.put("name","阅读量");
        seriesView.put("data",viewCounts);
        List<Map<String,Object>> seriesList = new ArrayList<>();
        seriesList.add(seriesWrit);
        seriesList.add(seriesView);

        countList.put("categories",months);
        countList.put("series",seriesList);
        return countList;
    }
    /**
     * 注册
     * */
    @Override
    public Result userRegister(RegisterDto registerDto) throws Exception {
        String key = registerDto.getKey();
        String verify = stringRedisTemplate.opsForValue().get(key);
        boolean nullOrEmpty = !StringUtil.isNullOrEmpty(verify);
        boolean equals = Integer.parseInt(verify) == registerDto.getVerify();
        if (nullOrEmpty&&equals){
            JournalUser journalUser = new JournalUser();
            journalUser.setPassword(rsaUtils.encrypt(registerDto.getPassword()));
            journalUser.setEmail(registerDto.getEmail());
            journalUser.setAuth(0);
            journalUser.setNickname("小日记"+ RandomUtil.randomNumbers(4));
            journalUser.setUsername(registerDto.getUsername());
            journalUser.setImgUrl(registerDto.getImgUrl());
            journalUser.setSign("写点什么吧~");
            int insert = journalUserMapper.insert(journalUser);
            if (insert == 1){
                return Result.success();
            }else {
                return Result.fail(ResultCode.ADD_FAIL);
            }
        }else {
            return Result.fail(ResultCode.ERROR);
        }

    }
    /**
     * 根据id查询用户信息
     * */
    @Override
    public JournalUser queryUserInfoById(int id) {
        JournalUser oneById = journalUserMapper.getOneById(id);
        return oneById;
    }

    @Override
    public Result journalNumberCountById(int id) {
        JournalNumberCountVo countNumberById = journalUserMapper.getCountNumberById(id);
        if (BeanUtil.isNotEmpty(countNumberById)){
            return Result.success(countNumberById);
        }else {
            return Result.fail(ResultCode.ERROR);
        }

    }

    @Override
    public int updateUserInfoById(JournalInfoDto journalInfoDto) {
        LambdaUpdateWrapper<JournalUser> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        if (!StringUtil.isNullOrEmpty(journalInfoDto.getSign())){
            lambdaUpdateWrapper.set(JournalUser::getSign,journalInfoDto.getSign());
        }
        if (!StringUtil.isNullOrEmpty(journalInfoDto.getNickName())){
            lambdaUpdateWrapper.set(JournalUser::getNickname,journalInfoDto.getNickName());
        }
        if (!StringUtil.isNullOrEmpty(journalInfoDto.getImgUrl())){
            lambdaUpdateWrapper.set(JournalUser::getImgUrl,journalInfoDto.getImgUrl());
        }
        if (!StringUtil.isNullOrEmpty(journalInfoDto.getEmail())){
            lambdaUpdateWrapper.set(JournalUser::getEmail,journalInfoDto.getEmail());
        }
        if (!StringUtil.isNullOrEmpty(journalInfoDto.getAge())){
            lambdaUpdateWrapper.set(JournalUser::getAge,journalInfoDto.getAge());
        }
        if (!StringUtil.isNullOrEmpty(journalInfoDto.getGender())){
            lambdaUpdateWrapper.set(JournalUser::getGender,journalInfoDto.getGender());
        }
        lambdaUpdateWrapper.eq(JournalUser::getId,journalInfoDto.getId());
        int update = journalUserMapper.update(null, lambdaUpdateWrapper);
        return update;
    }
    /**
     * 修改密码
     * */
    @Override
    public int updatePwd(String email, String pwd) throws Exception {
        String decrypt = rsaUtils.encrypt(pwd);
        int res= journalUserMapper.updatePasswordInt(email, decrypt);
        return res;
    }
    /**
     * 查询邮箱是否已经存在
     * */
    @Override
    public int selectEmail(String email) {
        int res = journalUserMapper.selectEmailInt(email);
        return res;
    }


    /**
     * 验证redis的key value
     * */
    public Result verifyRedis(String key,String value){
        String keyValue = stringRedisTemplate.opsForValue().get(key);
        if (!StringUtil.isNullOrEmpty(keyValue)){
            if (value.equals(keyValue)){
                return Result.success();
            }else {
                Result.fail(ResultCode.ERROR);
            }
        }else {
            Result.fail(ResultCode.ERROR);
        }
        return Result.fail(ResultCode.ERROR);
    }
}
